home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / util / snap_1_4 / part01 / source / snapgfx.c < prev   
C/C++ Source or Header  |  1990-02-11  |  8KB  |  260 lines

  1. /* Auto: make
  2. */
  3.  
  4. IMPORT struct SnapRsrc *SnapRsrc;
  5. IMPORT struct Image DiskImage;
  6. IMPORT struct Gadget DiskGad;
  7. IMPORT struct Gadget VProp, HProp;
  8. IMPORT struct PropInfo VInfo, HInfo;
  9. IMPORT struct Image VImage, HImage;
  10. IMPORT struct NewWindow Nw;
  11. IMPORT UBYTE *WindowTitle;
  12.  
  13. #define MINWIDTH (24 + SnapRsrc->GadOffset + 16)
  14. #define MINHEIGHT 15
  15.  
  16. LONG xl; /* leftmost x position */
  17. LONG xr; /* rightmost x position */
  18. LONG yt; /* topmost y position */
  19. LONG yb; /* bottommost y position */
  20. LONG mx, my; /* Mouse position in pixels */
  21.  
  22. #define GfxFrame 4L
  23. IMPORT Point OldFrame[];
  24. IMPORT Point NewFrame[];
  25. IMPORT LONG OFType;        /* Old frame type: ShortFrame/LongFrame */
  26. IMPORT UWORD Ptrn;
  27. IMPORT WORD Pattern[];
  28.  
  29. IMPORT struct RastPort MyRP;
  30. IMPORT struct BitMap MyBM;
  31. IMPORT struct Screen *theScreen;
  32. struct Layer_Info *LockedLayerInfo;
  33. IMPORT struct RastPort rp;
  34.  
  35. IMPORT LONGBITS cancelsignal, donesignal, movesignal, clicksignal, timersignal;
  36. IMPORT WORD action;
  37.  
  38. LONG TitleBarHeight;
  39. LONG ContentsFontHeight;
  40.  
  41. VOID FixHeights()
  42. {
  43.     struct Screen WBScreen;
  44.     if (GetScreenData((char *)&WBScreen, (LONG)sizeof(struct Screen), WBENCHSCREEN, NULL)) {
  45.           /* Now this is a good practice */
  46.         TitleBarHeight = WBScreen.RastPort.TxHeight+2;
  47.         ContentsFontHeight = WBScreen.Font->ta_YSize;
  48.     } else {
  49.           /* Sorry, but I don't realise how this could fail.
  50.              Well, if we're snapping on another screen and
  51.              WB is closed and it can't be opened by GetScreenData()...
  52.              Anyway, IF this should happen -- Use Topaz 8 */
  53.         TitleBarHeight = 10;
  54.         ContentsFontHeight = 8;
  55.     }
  56. }
  57.  
  58. /* SnapGfx is the actual graphics snapper.
  59. ** It steals the bitmap data from the given rastport
  60. ** and puts it in a separate bitmap.
  61. ** It also prepares the NewWindow structure according
  62. ** to the snapped bitmap.
  63. ** The coordinates are assumed to be valid.
  64. */
  65.  
  66. struct GfxSnap *SnapGfx(rp)
  67. struct RastPort *rp;
  68. {
  69.     struct GfxSnap *GS;
  70.     LONG i;
  71.  
  72.     GS = Create(GfxSnap);
  73.     if (!GS) {
  74.         return NULL;
  75.     }
  76.  
  77.     GS->x = xl;
  78.     GS->y = yt;
  79.     GS->width = xr - xl + 1;
  80.     GS->height = yb - yt + 1;
  81.     GS->depth = rp->BitMap->Depth;
  82.     GS->viewmode = theScreen->ViewPort.Modes;
  83.     GS->pagew = theScreen->Width;
  84.     GS->pageh = theScreen->Height;
  85.     i = (GS->viewmode & HAM ? 16 : 1L << GS->depth);
  86.       /* Copy the color map in case we should need it later */
  87.     while (i--) {
  88.         ULONG col = GetRGB4(theScreen->ViewPort.ColorMap, i);
  89.         GS->rgb[i][0] = ((col >> 8) & 0x0f) << 4;
  90.         GS->rgb[i][1] = ((col >> 4) & 0x0f) << 4;
  91.         GS->rgb[i][2] = ((col >> 0) & 0x0f) << 4;
  92.     }
  93.       /* Set up a nice bitmap */
  94.     InitBitMap(&GS->BM, GS->depth, GS->width, GS->height);
  95.       /* Get a handle on the bitmap */
  96.     InitRastPort(&MyRP);
  97.     MyRP.BitMap = &GS->BM;
  98.     if (!AllocPlanes(&GS->BM, GS->width, GS->height)) {
  99.         FreePlanes(&GS->BM, GS->width, GS->height);
  100.         Kill(GS);
  101.         return NULL;
  102.     }
  103.       /* Copy the selected part of the screen */
  104.     ClipBlit(rp, xl, yt, &MyRP, 0L, 0L, GS->width, GS->height, 0xC0L);
  105.     Nw.LeftEdge = xl;
  106.     Nw.TopEdge = yt;
  107.     Nw.Width = GS->width + 18;                   /* Two pixels on each side */
  108.     Nw.Height = GS->height + TitleBarHeight + 9; /* Bar & scroll bar */
  109.     Nw.Title = WindowTitle;
  110.     Nw.MaxWidth = Nw.Width;
  111.     Nw.MaxHeight = Nw.Height;
  112.     CopyMem((char *)&DiskGad, (char *)&GS->DiskGad,
  113.       (LONG)sizeof(DiskGad) + sizeof(VProp) + sizeof(HProp) +
  114.       sizeof(VInfo) + sizeof(HInfo) + sizeof(VImage) + sizeof(HImage));
  115.     GS->DiskGad.NextGadget = &GS->VProp;
  116.     GS->DiskGad.LeftEdge = -(SnapRsrc->GadOffset+16);
  117.     GS->DiskGad.Height = TitleBarHeight - 2;
  118.     DiskImage.Height = TitleBarHeight;
  119.     GS->VProp.NextGadget = &GS->HProp;
  120.     GS->VProp.TopEdge = TitleBarHeight;
  121.     GS->VProp.Height = -8 - TitleBarHeight;
  122.     GS->VProp.GadgetRender = (APTR)&GS->VImage;
  123.     GS->VProp.SpecialInfo = (APTR)&GS->VInfo;
  124.     GS->HProp.NextGadget = NULL;
  125.     GS->HProp.GadgetRender = (APTR)&GS->HImage;
  126.     GS->HProp.SpecialInfo = (APTR)&GS->HInfo;
  127.     return GS;
  128. }
  129.  
  130. VOID ExtendGfx()
  131. {
  132.     /* Fix which row we're talking about */
  133.     if (my-yt < yb-my) {       /* Find closest row */
  134.         yt = my;               /* change top row */
  135.     } else {
  136.         yb = my;               /* change bottom row */
  137.     }
  138.     if (mx-xl < xr-mx) {
  139.         xl = mx;
  140.     } else {
  141.         xr = mx;
  142.     }
  143. }
  144.  
  145. VOID gfx_frame()
  146. {
  147.     NewFrame[0].x = xl;  NewFrame[0].y = yt;
  148.     NewFrame[1].x = xr;  NewFrame[1].y = yt;
  149.     NewFrame[2].x = xr;  NewFrame[2].y = yb;
  150.     NewFrame[3].x = xl;  NewFrame[3].y = yb;
  151.     NewFrame[4].x = xl;  NewFrame[4].y = yt;
  152.     draw_frame(GfxFrame);
  153. }
  154.  
  155. WORD HandleGfx()
  156. {
  157.     theScreen = WhichScreen();   /* Find out where we are */
  158.     if (!theScreen) {            /* Don't know? Forget it. */
  159.         action = noaction;
  160.         return 0;
  161.     }
  162.       /* Lock everything - find out what happens */
  163.     LockedLayerInfo = &theScreen->LayerInfo;
  164.     LockLayers(LockedLayerInfo);
  165.  
  166.       /* Get a copy. Don't mess with somebody else's RP. */
  167.     CopyMem((char *)&theScreen->RastPort, (char *)&rp, (long)sizeof(struct RastPort));
  168.     SetDrMd(&rp, COMPLEMENT);
  169.  
  170.     xl = theScreen->MouseX + theScreen->ViewPort.RasInfo->RxOffset;
  171.     if (xl < 0) {
  172.         xl = 0;
  173.     }
  174.     if (xl >= theScreen->Width) {  /* Check those corners. Check those corners. */
  175.         xl = theScreen->Width - 1;
  176.     }
  177.     yt = theScreen->MouseY + theScreen->ViewPort.RasInfo->RyOffset;
  178.     if (yt < 0) {
  179.         yt = 0;
  180.     }
  181.     if (yt >= theScreen->Height) {
  182.         yt = theScreen->Height - 1;
  183.     }
  184.     xr = xl;
  185.     yb = yt;
  186.     Ptrn = (SnapRsrc->CrawlPtrn ? SnapRsrc->CrawlPtrn : Pattern[UNIT_FRAME]);
  187.     OFType = 0L;
  188.     gfx_frame();
  189.  
  190.     FOREVER {
  191.         REGISTER LONGBITS sig =
  192.           Wait(movesignal|clicksignal|cancelsignal|donesignal|timersignal);
  193.  
  194.         if ((sig & timersignal) && (SnapRsrc->CrawlPtrn != 0xffff)) {
  195.             crawl_frame(1L);
  196.         }
  197.  
  198.         if (sig & movesignal || sig & clicksignal) {
  199.             mx = theScreen->MouseX + theScreen->ViewPort.RasInfo->RxOffset;
  200.             if (mx < 0) {
  201.                 mx = 0;
  202.             }
  203.             if (mx>=theScreen->Width) {
  204.                 mx = theScreen->Width - 1;
  205.             }
  206.             my = theScreen->MouseY + theScreen->ViewPort.RasInfo->RyOffset;
  207.             if (my < 0) {
  208.                 my = 0;
  209.             }
  210.             if (my>=theScreen->Height) {
  211.                 my = theScreen->Height - 1;
  212.             }
  213.             ExtendGfx();
  214.             gfx_frame();
  215.         }
  216.         if (sig & cancelsignal) {          /* Cancelled? */
  217.             erase_frame();
  218.             UnlockLayers(LockedLayerInfo);
  219.             return 0;
  220.         }
  221.         if (sig & donesignal) {            /* Finished. Copy gfx. */
  222.             struct GfxSnap *GS;
  223.  
  224.             erase_frame();
  225.             if (xr < xl + MINWIDTH) {          /* Can't have too small windows */
  226.                 xr = xl + MINWIDTH;
  227.             }
  228.             if (xr >= theScreen->Width) {
  229.                 xl -= xr - theScreen->Width - 1;
  230.                 xr = theScreen->Width - 1;
  231.             }
  232.             if (yb < yt + MINHEIGHT) {
  233.                 yb = yt + MINHEIGHT;
  234.             }
  235.             if (yb >= theScreen->Height) {
  236.                 yt -= yb - theScreen->Height - 1;
  237.                 yb = theScreen->Height - 1;
  238.             }
  239.             FixHeights();
  240.             GS = SnapGfx(&rp); /* Snap! */
  241.             UnlockLayers(LockedLayerInfo);
  242.             if (GS) {
  243.                 if (GS->window = opensharedwindow(&Nw)) {
  244.                     GS->window->UserData = (BYTE *)GS;
  245.                       /* Put gfx in our new window */
  246.                     (VOID)AddGList(GS->window, &GS->DiskGad, 0L, 3L, NULL);
  247.                     RefreshGList(&GS->DiskGad, GS->window, NULL, 3L);
  248.                     AdjustSize(GS);
  249.                 } else {
  250.                     FreePlanes(&GS->BM, GS->width, GS->height);
  251.                     Kill(GS);
  252.                 }
  253.             } else { /* Good question */
  254.             }
  255.             action = noaction;
  256.             return 0;
  257.         }
  258.     }
  259. }
  260.